﻿
// **************************************************************************
//    Class Created by Mick Doherty (Dotnetrix) March 2010
//    http://dotnetrix.co.uk/
//
//    ...for GlassUI (an AeroGlass UI Library)
//    http://glassui.codeplex.com/
// **************************************************************************

using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using GlassUI.Design;
using System.Reflection;

namespace GlassUI
{
    public abstract class GlassControlBase : Control
    {
        internal GlassControlBase()
            : base()
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true);
        }

        private int m_CornerRadius = 5;
        private Corners m_RoundCorners;
        private bool defaultToGlass = true;

        private static Color defaultGlowColor = SystemColors.Highlight;
        private static Color ambientGlowColor = Color.Empty;
        private Color glowColor = ambientGlowColor;

        [Category("Appearance")]
        [DefaultValue(5)]
        [GlassUIDescription("CornerRadiusDescription")]
        public virtual int CornerRadius
        {
            get { return m_CornerRadius; }
            set
            {
                if (m_CornerRadius == value)
                    return;
                m_CornerRadius = value;
                this.Invalidate();
            }
        }

        [Category("Appearance")]
        [DefaultValue(typeof(Corners), "None")]
        [GlassUIDescription("RoundedCornersDescription")]
        public virtual Corners RoundedCorners
        {
            get { return m_RoundCorners; }
            set
            {
                if (m_RoundCorners == value)
                    return;
                m_RoundCorners = value;
                this.Invalidate();
            }
        }

        [Category("Behavior")]
        [DefaultValue(true)]
        [GlassUIDescription("DefaultToGlassDescription")]
        public bool DefaultToGlass
        {
            get { return defaultToGlass; }
            set { defaultToGlass = value; }
        }

        [Category("Appearance")]
        [AmbientValue(typeof(Color), "Empty")]
        [GlassUIDescription("GlowColorDescription")]
        public Color GlowColor
        {
            get 
            {
                if (this.glowColor == Color.Empty && this.Parent != null)
                {
                    Color color = ReflectedGlowColor(this.Parent);
                    if (!color.IsEmpty)
                        return color;
                    return GlassControlBase.defaultGlowColor;
                }
                return this.glowColor;
            }
            set { glowColor = value; }
        }

        public void ResetGlowColor()
        {
            this.GlowColor = GlassControlBase.ambientGlowColor;
        }

        private bool ShouldSerializeGlowColor()
        {
            return (this.glowColor != GlassControlBase.ambientGlowColor);
        }

        public override System.Drawing.Color BackColor
        {
            get
            {
                GlassForm form = this.FindForm() as GlassForm;
                if (form != null)
                {
                    if (DefaultToGlass && form.ControlIsOnGlass(this))
                        return Color.Transparent;
                }
                return base.BackColor;
            }
            set
            {
                base.BackColor = value;
            }
        }

        protected void DrawParentBackground(Graphics graphics)
        {
            System.Drawing.Drawing2D.GraphicsContainer g = graphics.BeginContainer();
            Rectangle translateRect = this.Bounds;
            graphics.TranslateTransform(-this.Left, -this.Top);
            PaintEventArgs pe = new PaintEventArgs(graphics, translateRect);
            this.InvokePaintBackground(this.Parent, pe);
            this.InvokePaint(this.Parent, pe);
            graphics.ResetTransform();
            graphics.EndContainer(g);
        }

        internal static Color ReflectedGlowColor(Control parent)
        {
            PropertyInfo info = parent.GetType().GetProperty("GlowColor");
            if (info != null)
                return (Color)info.GetValue(parent, null);
            GlassForm form = parent.FindForm() as GlassForm;
            if (form != null)
                return form.GlowColor;
            return Color.Empty;
        }

        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
            base.OnPaintBackground(pevent);
            if (this.BackColor.A < 255)
                DrawParentBackground(pevent.Graphics);
        }
    }
}
